﻿using System;
using System.Web.Mvc;
using TSites.UserMgmt;
using System.Collections;
using TSites.Common.Enums;
using TSites.Administrator.Models;
using TSites.Common.Const;
using System.Web.UI;
using System.Globalization;
using TSites.Core.Domain.UserMangerment;

namespace TSites.Administrator.Controllers
{
    public class UserManagementController : Controller
    {
		public IAdminMembership AdminMembershipService { get; set; }
        public IAdminSession AdminSessionService { get; set; }

		#region User functions
		
		public ActionResult Index()
        {
            return View();
        }

		public ActionResult Search(string userId, string username, string email,
			int? actCode, int curPage, int pageSize)
		{
			int activeCode = actCode.HasValue ? actCode.Value : -1;
			pageSize = 2;
			int totalItems;
			IList userList = AdminMembershipService.GetUsers(userId, username, email,
				activeCode, curPage, pageSize, out totalItems);

			ViewBag.PageInfo = new PagingInfo()
			{
				PageIndex = curPage,
				PageSize = pageSize,
				TotalItems = totalItems
			};

			return View(userList);
		}

		[HttpGet]
        public ActionResult Add()
        {
            return View();
        }

        [HttpPost]
		public ActionResult Add(UserAddViewModel user)
        {
            if (ModelState.IsValid)
            {
				// sex
                string sex = Request.Form["rdoMale"];
                user.Sex = sex != null ? sex[0] : Request.Form["rdoFemale"][0];
				// day of birth
				string dob = Request.Form["txtDOB"];
				DateTime dayofbirth;
				if (DateTime.TryParseExact(dob, "dd/mm/yyyy", null, DateTimeStyles.None, out dayofbirth))
				{
					user.DateOfBirth = dayofbirth;
				}

				string createdUsrId, reason;
#if DEBUG
				createdUsrId = "Admin";
#else
                createdUsrId = AdminSessionService.CurrentAdmin.UserId;
#endif
				reason = "AddBy" + createdUsrId;

				User addedUser = user.Convert2User();
				addedUser.CreateUserId = createdUsrId;
				addedUser.Reason = reason;
				RET_CODE retCode = AdminMembershipService.RegisterUser(addedUser);
                switch (retCode)
                {
                    case RET_CODE.SUCCESS:
                        TempData["UserMgmt.Add"] = "Create user successfully";
                        return View("Search");

					case RET_CODE.USERID_EMAIL_EXISTED:
						ModelState.AddModelError("UserId", "UserId may existed");
						ModelState.AddModelError("Email", "Email may existed");
						break;
                   
                    case RET_CODE.DB_ERROR:
                    default:
                        ModelState.AddModelError("Error", "Error occurs");
                        break;
                }
            }
            return View();
        }

		[HttpGet]
		public ActionResult Edit(string id)
		{
			TSites.Core.Domain.UserMangerment.User currentUser = AdminMembershipService.GetByUserId(id);
			UserEditViewModel userEditView = new UserEditViewModel()
			{
				UserId = currentUser.ID,
				Username = currentUser.UserName,
				Password = currentUser.Password,
				Email = currentUser.Email,
				Sex = currentUser.Sex[0],
				DateOfBirth = currentUser.DateOfBirth.HasValue ? currentUser.DateOfBirth.Value : DateTime.MinValue,
				Address = ((Address)currentUser.Addresses[0]).UserAddress,
				PhoneNumber = ((Phone)currentUser.Phones[0]).PhoneNumber
			};
			return View(userEditView);
		}

		[HttpPost]
		public ActionResult Edit(UserEditViewModel user)
		{
			if (ModelState.IsValid)
			{
				// sex
				string sex = Request.Form["rdoMale"];
				user.Sex = sex != null ? sex[0] : Request.Form["rdoFemale"][0];

				string updatedUsrId, reason;
#if DEBUG
				updatedUsrId = "Admin";
#else
                updatedUsrId = AdminSessionService.CurrentAdmin.UserId;
#endif
				reason = "UpdateBy" + updatedUsrId;

				User updatedUser = user.Convert2User();
				updatedUser.UpdateUserId = updatedUsrId;
				updatedUser.Reason = reason;
				RET_CODE retCode = AdminMembershipService.UpdateUser(updatedUser);
				switch (retCode)
				{
					case RET_CODE.SUCCESS:
						TempData["UserMgmt.Update"] = "Update user successfully";
                        return RedirectToAction("Index");

					case RET_CODE.EMAIL_EXISTED:
						ModelState.AddModelError("Email", "Email is used by another User");
						break;

					case RET_CODE.DB_ERROR:
					default:
						ModelState.AddModelError("Error", "Error occurs");
						break;
				}
			}

			return View(user);
		}

		[HttpPost]
		public ActionResult Delete(string id)
		{
			string errorString = string.Empty;
			RET_CODE retCode = AdminMembershipService.DeleteUser(id);
			switch (retCode)
			{
				case RET_CODE.SUCCESS:
					TempData["UserMgmt.Delete"] = "Delete user successfully";
					return View("Search");

				case RET_CODE.USERID_DOES_NOT_EXISTED:
					errorString = "User does not exist";
					break;

				case RET_CODE.DB_ERROR:
					errorString = "Database is error. Please try again";
					break;

				default:
					errorString = "Error";
					break;
			}

			return View(id);
		}

		[HttpPost]
		public ActionResult ResetUserPwd(string id)
		{
			string errorString = string.Empty;
			string updatedUsrId = AdminSessionService.CurrentAdmin.UserId;

			RET_CODE retCode = AdminMembershipService.RetsetUserPassword(id, updatedUsrId);
			switch (retCode)
			{
				case RET_CODE.SUCCESS:
					TempData["UserMgmt.ResetUserPwd"] = "Reset password for user successfully";
					return View("Search");

				case RET_CODE.USERID_DOES_NOT_EXISTED:
					errorString = "User does not exist";
					break;

				case RET_CODE.EMAIL_DOES_NOT_EXISTED:
					errorString = "Email does not exist";
					break;

				case RET_CODE.DB_ERROR:
					errorString = "Database is error. Please try again";
					break;

				default:
					errorString = "Error";
					break;
			}

			return View(id);
		}

		[HttpPost]
		public ActionResult UpdateActiveCode(string userId, int activeCode, string reason)
		{
			string errorString = string.Empty;
			string updatedUsrId = AdminSessionService.CurrentAdmin.UserId;
			RET_CODE retCode = AdminMembershipService.UpdateActiveCode(
				userId, activeCode, reason, updatedUsrId);
			switch (retCode)
			{
				case RET_CODE.SUCCESS:
					break;

				case RET_CODE.DB_ERROR:
					errorString = "Database is error. Please try again";
					break;

				default:
					errorString = "Error";
					break;
			}

			return View();
		}

		[HttpPost]
		public ActionResult ActiveUserByVerifyKey(string key)
		{
			string errorString = string.Empty;
			RET_CODE retCode = AdminMembershipService.ActiveByKeyVerify(key);
			switch (retCode)
			{
				case RET_CODE.SUCCESS:
					break;

				case RET_CODE.INVALID_KEY_VERIFY:
					errorString = "Verify key is invalid";
					break;

				case RET_CODE.KEY_VERIFY_IS_EXPIRED:
					errorString = "Verify key is expired";
					break;

				case RET_CODE.DB_ERROR:
					errorString = "Database is error. Please try again";
					break;

				default:
					errorString = "Error";
					break;
			}

			return View();
		}

		#endregion

		#region Owner functions
		
		[HttpPost]
		public ActionResult ChangePassword(ChangePasswordViewModel changePwd)
		{
			if (ModelState.IsValid)
			{
				string errorString = string.Empty;
                string userId = AdminSessionService.CurrentAdmin.UserId;
				RET_CODE retCode = AdminMembershipService.ChangePassword(
					userId,
					changePwd.CurrentPassword,
					changePwd.NewPassword);
				switch (retCode)
				{
					case RET_CODE.SUCCESS:
						return RedirectToAction("Index");

					case RET_CODE.USERID_DOES_NOT_EXISTED:
						errorString = "User does not exist";
						break;

					case RET_CODE.WRONG_PASSWORD:
						errorString = "Current password is not correct";
						break;

					case RET_CODE.DB_ERROR:
						errorString = "Database is error. Please try again";
						break;

					default:
						errorString = "Error";
						break;
				}
				ModelState.AddModelError(string.Empty, errorString);
			}

			return View(changePwd);
		}

		[HttpPost]
		public ActionResult ForgotPassword(string email)
		{
			if (ModelState.IsValid)
			{
				string errorString = string.Empty;
				RET_CODE retCode = AdminMembershipService.ForgotPassword(email);
				switch (retCode)
				{
					case RET_CODE.SUCCESS:
						break;

					case RET_CODE.EMAIL_DOES_NOT_EXISTED:
						errorString = "Email does not exist";
						break;

					case RET_CODE.DB_ERROR:
						errorString = "Database is error. Please try again";
						break;

					default:
						errorString = "Error";
						break;
				}
				ModelState.AddModelError(string.Empty, errorString);
			}

			return View(email);
		}

		[HttpPost]
		public ActionResult UpdateUser()
		{
			if (ModelState.IsValid)
			{
				string errorString = string.Empty;
				RET_CODE retCode = AdminMembershipService.UpdateUser(null);
				switch (retCode)
				{
					case RET_CODE.SUCCESS:
						break;

					case RET_CODE.DB_ERROR:
						errorString = "Database is error. Please try again";
						break;

					default:
						errorString = "Error";
						break;
				}
			}
			
			return View();
		}

		#endregion

		#region Validations
		
		[OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
		public JsonResult IsUserIdAvailable(string userId)
        {
			if (AdminMembershipService != null)
			{
				RET_CODE retCode = AdminMembershipService.UserExists(userId);
				if (retCode == RET_CODE.SUCCESS)
				{
					return Json(true, JsonRequestBehavior.AllowGet);
				}
			}

            string suggestedUsrId = String.Format(CultureInfo.InvariantCulture,
                "{0} is not available", userId);
            return Json(suggestedUsrId, JsonRequestBehavior.AllowGet);
        }

		[OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
		public JsonResult IsEmailAvailable(string email)
		{
			RET_CODE retCode = AdminMembershipService.EmailExists(email);
			if (retCode == RET_CODE.SUCCESS)
			{
				return Json(true, JsonRequestBehavior.AllowGet);
			}

			string suggestedEmail = String.Format(CultureInfo.InvariantCulture,
				"{0} is not available", email);
			return Json(suggestedEmail, JsonRequestBehavior.AllowGet);
		}

		[OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
		public JsonResult IsEmail4EditAvailable(string email, string userId)
		{
			RET_CODE retCode = AdminMembershipService.EmailExists(email, userId);
			if (retCode == RET_CODE.SUCCESS)
			{
				return Json(true, JsonRequestBehavior.AllowGet);
			}

			string suggestedEmail = String.Format(CultureInfo.InvariantCulture,
				"{0} is not available", email);
			return Json(suggestedEmail, JsonRequestBehavior.AllowGet);
		}

		#endregion
	}
}
